import datetime
from app.core.extensions import db


class Agent(db.Model):
    """代理商模型"""
    __tablename__ = 'agents'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False, comment='代理名称')
    level = db.Column(db.Integer, default=1, comment='代理等级：1=普通代理，2=高级代理，3=区域代理')
    parent_id = db.Column(db.Integer, db.ForeignKey('agents.id'), nullable=True, comment='上级代理ID')
    user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), comment='关联用户ID')
    mobile = db.Column(db.String(20), comment='手机号码')
    email = db.Column(db.String(100), comment='电子邮箱')
    commission_rate = db.Column(db.Float, default=0.1, comment='佣金比例')
    max_generation_count = db.Column(db.Integer, default=100, comment='最大可生成激活码数量')
    used_generation_count = db.Column(db.Integer, default=0, comment='已使用的激活码生成数量')
    balance = db.Column(db.Numeric(10, 2), default=0, comment='账户余额')
    status = db.Column(db.Integer, default=1, comment='状态：1=启用，0=禁用')
    region = db.Column(db.String(100), comment='负责区域')
    remark = db.Column(db.Text, comment='备注')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')
    # 关系
    parent = db.relationship('Agent', remote_side=[id], backref='children')
    user = db.relationship('User', backref=db.backref('agent', uselist=False))

    def get_level_name(self):
        level_map = {
            1: '普通代理',
            2: '高级代理',
            3: '区域代理'
        }
        return level_map.get(self.level, '未知等级')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'level': self.level,
            'level_name': self.get_level_name(),
            'parent_id': self.parent_id,
            'parent_name': self.parent.name if self.parent else None,
            'mobile': self.mobile,
            'email': self.email,
            'user_id': self.user_id,
            'commission_rate': self.commission_rate,
            'max_generation_count': self.max_generation_count,
            'used_generation_count': self.used_generation_count,
            'remaining_count': self.max_generation_count - self.used_generation_count,
            'balance': float(self.balance) if self.balance else 0.0,
            'status': self.status,
            'status_text': '启用' if self.status == 1 else '禁用',
            'region': self.region,
            'remark': self.remark,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S'),
            'has_children': len(self.children) > 0,
            'tenant_id': self.tenant_id,
        }

    def get_level_name(self):
        level_names = {
            1: '普通代理',
            2: '高级代理',
            3: '区域代理',
            4: '总代理'
        }
        return level_names.get(self.level, '未知等级')

    def get_all_children(self):
        """获取所有下级代理(递归)"""
        all_children = []
        for child in self.children:
            all_children.append(child)
            all_children.extend(child.get_all_children())
        return all_children

    def get_team_size(self):
        """获取团队规模(所有下级数量)"""
        return len(self.get_all_children())

    def get_team_performance(self):
        """获取团队业绩"""
        # 从同一个模块导入Order
        # 查询团队订单总额
        team_ids = [self.id]
        for child in self.get_all_children():
            team_ids.append(child.id)

        total = Order.query.with_entities(db.func.sum(Order.amount)) \
                    .filter(Order.agent_id.in_(team_ids)) \
                    .scalar() or 0

        return float(total)


class Commission(db.Model):
    """佣金记录模型"""
    __tablename__ = 'commissions'

    id = db.Column(db.Integer, primary_key=True)
    agent_id = db.Column(db.Integer, db.ForeignKey('agents.id'), comment='代理ID')
    order_id = db.Column(db.String(64), db.ForeignKey('orders.id'), comment='订单ID')
    amount = db.Column(db.Numeric(10, 2), comment='佣金金额')
    rate = db.Column(db.Float, comment='佣金比例')
    level = db.Column(db.Integer, comment='获得佣金的层级：0=直接佣金，1=一级下线佣金，2=二级下线佣金')
    status = db.Column(db.Integer, default=0, comment='状态：0=待结算，1=已结算')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    settle_time = db.Column(db.DateTime, comment='结算时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')
    # 关系
    agent = db.relationship('Agent', backref='commissions')

    def to_dict(self):
        return {
            'id': self.id,
            'agent_id': self.agent_id,
            'agent_name': self.agent.name if self.agent else None,
            'order_id': self.order_id,
            'amount': float(self.amount) if self.amount else 0.0,
            'rate': self.rate,
            'level': self.level,
            'level_name': self.get_level_name(),
            'status': self.status,
            'status_text': '已结算' if self.status == 1 else '待结算',
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S'),
            'settle_time': self.settle_time.strftime('%Y-%m-%d %H:%M:%S') if self.settle_time else None,
            'tenant_id': self.tenant_id
        }

    def get_level_name(self):
        level_names = {
            0: '直接佣金',
            1: '一级下线佣金',
            2: '二级下线佣金',
            3: '三级下线佣金'
        }
        return level_names.get(self.level, f'{self.level}级下线佣金')


class ActivationCodeBatch(db.Model):
    __tablename__ = 'activation_code_batches'
    id = db.Column(db.String(32), primary_key=True, comment='批次ID')
    agent_id = db.Column(db.Integer, db.ForeignKey('agents.id'), nullable=False, comment='代理ID')
    count = db.Column(db.Integer, nullable=False, comment='生成数量')
    usage_count = db.Column(db.Integer, nullable=False, comment='每个激活码的使用次数')
    expire_days = db.Column(db.Integer, nullable=True, comment='有效天数')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    remark = db.Column(db.String(255), nullable=True, comment='备注')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')
    # 关联关系
    agent = db.relationship('Agent', backref=db.backref('batches', lazy=True))


class ActivationCode(db.Model):
    __tablename__ = 'activation_codes'
    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(16), unique=True, nullable=False, comment='激活码')
    usage_count = db.Column(db.Integer, default=10, comment='可增加的使用次数')
    status = db.Column(db.Integer, default=0, comment='状态: 0-未使用 1-已使用')
    used_by = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=True, comment='使用者ID')
    used_time = db.Column(db.DateTime, nullable=True, comment='使用时间')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    expire_time = db.Column(db.DateTime, nullable=True, comment='过期时间')
    remark = db.Column(db.String(255), nullable=True, comment='备注')
    created_by = db.Column(db.Integer, db.ForeignKey('agents.id'), nullable=True, comment='创建者ID(代理ID)')
    batch_id = db.Column(db.String(32), db.ForeignKey('activation_code_batches.id'), nullable=True, comment='批次ID')
    is_copied = db.Column(db.Boolean, default=False, comment='是否已复制: 0-未复制, 1-已复制')
    is_exported = db.Column(db.Boolean, default=False, comment='是否已导出: 0-未导出, 1-已导出')
    copied_time = db.Column(db.DateTime, nullable=True, comment='复制时间')
    exported_time = db.Column(db.DateTime, nullable=True, comment='导出时间')
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')
    # 关联关系
    user = db.relationship('User', backref=db.backref('activation_codes', lazy=True))
    agent = db.relationship('Agent', backref=db.backref('codes', lazy=True))
    batch = db.relationship('ActivationCodeBatch', backref=db.backref('codes', lazy=True))

    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'code': self.code,
            'usage_count': self.usage_count,
            'status': self.status,
            'status_text': '已使用' if self.status == 1 else '未使用',
            'used_by': self.used_by,
            'user_name': self.user.nick_name if self.user else None,
            'used_time': self.used_time.strftime('%Y-%m-%d %H:%M:%S') if self.used_time else None,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'expire_time': self.expire_time.strftime('%Y-%m-%d %H:%M:%S') if self.expire_time else None,
            'remark': self.remark,
            'created_by': self.created_by,
            'agent_name': self.agent.name if self.agent else None,
            'batch_id': self.batch_id,
            'is_copied': self.is_copied,
            'is_exported': self.is_exported,
            'copied_time': self.copied_time.strftime('%Y-%m-%d %H:%M:%S') if self.copied_time else None,
            'exported_time': self.exported_time.strftime('%Y-%m-%d %H:%M:%S') if self.exported_time else None,
            'tenant_id': self.tenant_id
        }


class Order(db.Model):
    """订单表"""
    __tablename__ = 'orders'

    id = db.Column(db.String(64), primary_key=True, comment='订单号，使用ORD+时间戳+用户ID后缀')
    user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False, comment='用户ID')
    amount = db.Column(db.DECIMAL(10, 2), nullable=False, comment='订单金额（元）')
    total_fee = db.Column(db.Integer, nullable=False, comment='支付金额（分）')
    plan_id = db.Column(db.Integer, db.ForeignKey('plans.id'), nullable=True, comment='套餐ID')
    times = db.Column(db.Integer, nullable=False, comment='增加使用次数')
    title = db.Column(db.String(100), nullable=False, default='购买次数', comment='商品标题')
    status = db.Column(db.String(20), nullable=False, default='PENDING',
                       comment='订单状态: PENDING-待支付, PAID-已支付, CLOSED-已关闭')
    transaction_id = db.Column(db.String(64), nullable=True, comment='微信支付交易号')
    prepay_id = db.Column(db.String(64), nullable=True, comment='微信预支付ID')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    paid_time = db.Column(db.DateTime, nullable=True, comment='支付时间')
    notify_time = db.Column(db.DateTime, nullable=True, comment='回调通知时间')
    ip = db.Column(db.String(50), nullable=True, comment='用户IP')
    openid = db.Column(db.String(50), nullable=True, comment='用户openid')
    remark = db.Column(db.String(255), nullable=True, comment='备注')
    agent_id = db.Column(db.Integer, db.ForeignKey('agents.id'), nullable=True, comment='代理ID')
    platform_type = db.Column(db.String(20), nullable=False, comment='支付平台')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')
    # 关系
    agent = db.relationship('Agent', backref='orders')

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'amount': str(self.amount),
            'total_fee': self.total_fee,
            'plan_id': self.plan_id,
            'times': self.times,
            'title': self.title,
            'status': self.status,
            'platform_type': self.platform_type,
            'transaction_id': self.transaction_id,
            'prepay_id': self.prepay_id,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'paid_time': self.paid_time.strftime('%Y-%m-%d %H:%M:%S') if self.paid_time else None,
            'notify_time': self.notify_time.strftime('%Y-%m-%d %H:%M:%S') if self.notify_time else None,
            'ip': self.ip,
            'openid': self.openid,
            'remark': self.remark,
            'agent_id': self.agent_id,
            'agent_name': self.agent.name if self.agent else None,
            'tenant_id': self.tenant_id
        }


class PaymentLog(db.Model):
    """支付记录表"""
    __tablename__ = 'payment_logs'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    order_id = db.Column(db.String(64), db.ForeignKey('orders.id'), nullable=False, comment='订单号')
    transaction_id = db.Column(db.String(64), nullable=True, comment='微信支付交易号')
    amount = db.Column(db.DECIMAL(10, 2), nullable=False, comment='支付金额（元）')
    payment_type = db.Column(db.String(20), nullable=False, default='WXPAY', comment='支付方式: WXPAY-微信支付')
    status = db.Column(db.String(20), nullable=False, comment='支付状态')
    raw_data = db.Column(db.Text, nullable=True, comment='原始支付数据')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')


class PaymentNotification(db.Model):
    """支付通知记录表"""
    __tablename__ = 'payment_notifications'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    order_id = db.Column(db.String(64), db.ForeignKey('orders.id'), nullable=False, comment='订单号')
    transaction_id = db.Column(db.String(64), nullable=True, comment='微信支付交易号')
    notification_type = db.Column(db.String(20), nullable=False, comment='通知类型: PAY-支付通知, REFUND-退款通知')
    status = db.Column(db.String(20), nullable=False, comment='通知状态: SUCCESS-成功, FAIL-失败')
    raw_data = db.Column(db.Text, nullable=True, comment='原始通知数据')
    processed = db.Column(db.Boolean, nullable=False, default=False, comment='是否已处理: 0-未处理, 1-已处理')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')


class Plan(db.Model):
    """商品/套餐表"""
    __tablename__ = 'plans'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100), nullable=False, comment='套餐名称')
    amount = db.Column(db.DECIMAL(10, 2), nullable=False, comment='套餐价格（元）')
    times = db.Column(db.Integer, nullable=False, comment='增加使用次数')
    description = db.Column(db.Text, nullable=True, comment='套餐描述')
    status = db.Column(db.Boolean, nullable=False, default=True, comment='状态: 0-禁用, 1-启用')
    sort = db.Column(db.Integer, default=0, comment='排序')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    update_time = db.Column(db.DateTime, onupdate=datetime.datetime.now, comment='更新时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'amount': str(self.amount),
            'times': self.times,
            'description': self.description,
            'status': self.status,
            'sort': self.sort,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'update_time': self.update_time.strftime('%Y-%m-%d %H:%M:%S') if self.update_time else None,
            'tenant_id': self.tenant_id
        }


class UsageRecord(db.Model):
    """使用记录表"""
    __tablename__ = 'usage_records'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=False, comment='用户ID')
    source_type = db.Column(db.String(20), nullable=False, comment='来源类型: ORDER-购买, CODE-激活码, SHARE-分享')
    source_id = db.Column(db.String(64), nullable=True, comment='来源ID（订单号或激活码）')
    times = db.Column(db.Integer, nullable=False, comment='增加的使用次数')
    remark = db.Column(db.String(255), nullable=True, comment='备注')
    create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'source_type': self.source_type,
            'source_id': self.source_id,
            'times': self.times,
            'remark': self.remark,
            'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S') if self.create_time else None,
            'tenant_id': self.tenant_id
        }
